<?php
defined('SYSPATH') or die('No direct script access.');

class Controller_Stats extends Controller_Initialize {

  public $secure_actions = array(
      // user actions
      'index' => 'admin',
      );

    public function action_index() {

      $this->template->navigation->active = 'admin';

      // lists of months and years for the dropdowns
		list($months, $years, $first, $last) = $this->generate_months_years(ORM::factory('hit_visitor'), 'date');
		$month = Arr::get($_POST, 'month', sprintf('%d%02d', $last['year'], $last['month']));
		$year = Arr::get($_POST, 'year', $last['year']);

      // daily plot
      if(!empty($_POST)) {
        $visitors_daily = ORM::factory('hit_visitor')
              ->select(new Database_Expression('COUNT(*) AS total'))
              ->with('date')
              ->group_by('date_id')
              ->order_by('date.datestamp', 'DESC')
              ->where('date.datestamp', 'LIKE', "$month%")
              ->where('incognito', '=', 0)
              ->find_all()->as_array();
        $daily = $this->generate_data_series($visitors_daily, 'DAILY', 'date');

      } else {
        $visitors_daily = ORM::factory('hit_visitor')
              ->select(new Database_Expression('COUNT(*) AS total'))
              ->with('date')
              ->group_by('date_id')
              ->order_by('date.datestamp', 'DESC')
              ->where('incognito', '=', 0)
              ->limit(30)
              ->find_all()->as_array();
        $daily = $this->generate_data_series($visitors_daily, 'DAILY', 'date');
        $daily['values'] = array_slice($daily['values'],-30,30);
      }

      // monthly plot
      if(!empty($_POST)) {
        $visitors_monthly = ORM::factory('hit_visitor')
              ->select(new Database_Expression('COUNT(*) AS total'))
              ->with('date')
              ->group_by('date.year', 'date.month')
              ->order_by('date.year', 'DESC')
              ->order_by('date.month', 'DESC')
              ->where('date.year', '=', $year)
              ->where('incognito', '=', 0)
              ->find_all()->as_array();
        $monthly = $this->generate_data_series($visitors_monthly, 'MONTHLY', 'date');
      } else {
        $visitors_monthly = ORM::factory('hit_visitor')
              ->select(new Database_Expression('COUNT(*) AS total'))
              ->with('date')
              ->group_by('date.year', 'date.month')
              ->order_by('date.year', 'DESC')
              ->order_by('date.month', 'DESC')
              ->where('incognito', '=', 0)
              ->find_all()->as_array();
        $monthly = $this->generate_data_series($visitors_monthly, 'MONTHLY', 'date');
        $monthly['values'] = array_slice($monthly['values'],-12,12);
      }

      $top_hits = ORM::factory('hit_uri')->where('stats_me', '=', true)->order_by('hits', 'DESC')->find_all();

      $this->template->content = View::factory('templates/stats/index')
        ->bind('daily', $daily)
        ->bind('monthly', $monthly)
        ->bind('top_hits', $top_hits);
   
    }

    protected function generate_months_years($model, $with = '') {
            $m1 = clone $model;
            if (!empty($with)) {
                    $m1->with($with);
            }
            $objs = $m1->order_by('datestamp', 'ASC')->find_all();
            if (empty($objs)) {
                    $cur = getdate();
                    $month = sprintf('%d%02d', $cur['year'], $cur['mon']);
                    $emptymonths = array(
                            "$month" => sprintf('%d/%02d', $cur['year'], $cur['mon']),
                    );
                    $empty = array(
                            'year' => $cur['year'],
                            'month' => $cur['mon'],
                    );
                    return array($emptymonths, array( "{$cur['year']}" => $cur['year'] ), $empty, $empty);
            }
            $first_obj = $objs[0];
            $last_obj = $objs[count($objs) - 1];
            if (!empty($with)) {
                    foreach (explode(':', $with) as $accessor) {
                            $first_obj = $first_obj->$accessor;
                            $last_obj = $last_obj->$accessor;
                    }
            }
            $first = array('year' => $first_obj->year, 'month' => $first_obj->month);
            $last = array('year' => $last_obj->year, 'month' => $last_obj->month);
            $months = array();
            $years = array();
            $cur = $first;
            while ($cur['year'] < $last['year'] or $cur['month'] <= $last['month']) {
                    if ($cur['month'] == 13) {
                            $cur['month'] = 1;
                            $cur['year']++;
                    }
                    if (!isset($years[$cur['year']])) {
                            $years[$cur['year']] = $cur['year'];
                    }
                    $months[sprintf('%d%02d', $cur['year'], $cur['month'])] = sprintf('%d/%02d', $cur['year'], $cur['month']);
                    $cur['month']++;
            }
            $months = array_reverse($months, TRUE);
            $years = array_reverse($years, TRUE);
            return array($months, $years, $first, $last);
    }

    protected function generate_data_series($model, $mode, $accessor = '', $firstdate = NULL) {
            switch ($mode) {

            case 'DAILY':
                    $daily = array(
                            'values' => array(),
                            'max' => 0,
                    );
                    $timestamp = 0;
                    $timestamp_b4 = 0;
                    $firstdata = NULL;
                    foreach (array_reverse($model) as $obj) {
                            $objdate = (empty($accessor)? $obj : $obj->$accessor);
                            $timestamp = gmmktime(0, 0, 0, $objdate->month, $objdate->date, $objdate->year) * 1000;
                            if (empty($daily['values'])) {
                                    // reset $timestamp_b4 to the first day of the month
                                    $month_b4 = $objdate->month - 1;
                                    $year_b4 = $objdate->year;
                                    if ($month_b4 == 0) {
                                            $month_b4 = 12; $year_b4--;
                                    }
                                    $timestamp_b4 = gmmktime(0, 0, 0, $month_b4, cal_days_in_month(CAL_GREGORIAN, $month_b4, $year_b4), $year_b4) * 1000;
                                    $firstdata = $objdate;
                            }
                            while ($timestamp - $timestamp_b4 > 86400000) {
                                    // fill up days of the month that didn't have visitors to 0
                                    $timestamp_b4 += 86400000;
                                    $daily['values']["$timestamp_b4"] = array($timestamp_b4, 0);
                            }
                            if (isset($daily['values']["$timestamp"])) {
                                    $daily['values']["$timestamp"][1] += $obj->total;
                            }
                            else {
                                    $daily['values']["$timestamp"] = array($timestamp, $obj->total);
                            }
                            if ($daily['values']["$timestamp"][1] > $daily['max']) {
                                    $daily['max'] = $daily['values']["$timestamp"][1];
                            }
                            $timestamp_b4 = $timestamp;
                            $month_b4 = $objdate->month;
                            $year_b4 = $objdate->year;
                    }
                    if ($firstdata) {
                            // fill up to the end of the month
                            $timestamp_endofmonth = gmmktime(0, 0, 0, $firstdata->month, cal_days_in_month(CAL_GREGORIAN, $firstdata->month, $firstdata->year), $firstdata->year) * 1000;
                            $cur = getdate();
                            $ctime = gmmktime(0, 0, 0, $cur['mon'], $cur['mday'], $cur['year']) * 1000 - 86400000;
                            while ($timestamp_endofmonth - $timestamp > 0 and $timestamp <= $ctime) {
                                    $timestamp += 86400000;
                                    $daily['values']["$timestamp"] = array($timestamp, 0);
                            }
                    }
                    return $daily;

            default:
                    $monthly = array(
                            'values' => array(),
                            'max' => 0,
                    );
                    $year_b4 = 0;
                    $month_b4 = 0;
                    $timestamp = 0;
                    foreach (array_reverse($model) as $obj) {
                            $objdate = (empty($accessor)? $obj : $obj->$accessor);
                            if (empty($monthly['values'])) {
                                    // reset $month_b4 to the first month of the year
                                    $year_b4 = $objdate->year;
                                    $month_b4 = 0;
                            }
                            while ($year_b4 < $objdate->year or $month_b4 + 1 < $objdate->month) {
                                    $month_b4++;
                                    if ($month_b4 == 13) {
                                            $month_b4 = 1;
                                            $year_b4++;
                                    }
                                    $timestamp = gmmktime(0, 0, 0, $month_b4, 1, $year_b4) * 1000;
                                    $monthly['values']["$timestamp"] = array($timestamp, 0);
                            }
                            $timestamp = gmmktime(0, 0, 0, $objdate->month, 1, $objdate->year) * 1000;
                            if (isset($monthly['values']["$timestamp"])) {
                                    $monthly['values']["$timestamp"][1] += $obj->total;
                            }
                            else {
                                    $monthly['values']["$timestamp"] = array($timestamp, $obj->total);
                            }
                            if ($monthly['values']["$timestamp"][1] > $monthly['max']) {
                                    $monthly['max'] = $monthly['values']["$timestamp"][1];
                            }
                            $year_b4 = $objdate->year;
                            $month_b4 = $objdate->month;
                    }
                    // Pokud je odeslan POST, doplni pro uplnost zbyvajici mesice vybraneho roku i kdyz nemaji dosud zadne navstevy
                    if ($year_b4 > 0 && !empty($_POST)) {
                            $ctime = time() * 1000 - 86400000;
                            $thisyear = intval(date('Y'));
                            $thismonth = intval(date('n'));
                            while ($month_b4 < 12 and !($year_b4 == $thisyear and $month_b4 == $thismonth)) {
                                    $month_b4++;
                                    $timestamp = gmmktime(0, 0, 0, $month_b4, 1, $year_b4) * 1000 ;
                                    $monthly['values']["$timestamp"] = array($timestamp, 0);
                            }
                    }
                    return $monthly;
            }
    }

    public function after() {

      if ($this->auto_render) {
        $scripts = array('media/js/flot/jquery.flot.js','media/js/flot/jquery.flot.selection.js','media/js/flot/jquery.flot.stack.js','media/js/flot/jquery.flot.pie.js');
        $this->template->scripts = array_reverse(array_merge($this->template->scripts, $scripts));
      }

      // Run anything that needs to run after this.
      parent::after();
    }
 } // End